﻿using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using PersistanceLayer;

namespace BusinessLayer
{
    internal class ChatBoxService : IChatBoxService
    {
        private static IList<ChatBoxUser> _users = new List<ChatBoxUser>();
        private static IList<ChatBoxMessage> _messages = new List<ChatBoxMessage>();
        private static Thread _thread;

        private IChatBoxDataRepository _repository = RepositoryFactory.CreateNewRepository();

        public ChatBoxService()
        {
            if (_thread == null)
                _thread = new Thread(ChatBoxCleanup);
            if (!_thread.IsAlive) _thread.Start();
        }

        private void ChatBoxCleanup()
        {
            var seconds = 2;
            while (true)
            {
                Thread.Sleep(seconds * 1000);

                _repository.ChangeIsOnlinePropertyWhenAppropriate(15);


                //lock (_users)
                //{
                //    var tempUsers=new List<ChatBoxUser>();
                //    tempUsers.AddRange(from user in _users let timeSpan = DateTime.Now.Subtract(user.LastSeen) where timeSpan.TotalSeconds <= 6 select user);
                //    _users = tempUsers;
                //}
            }

        }

        public int Login(string name, Position position)
        {
            var iconUrl = PrepareIconUrl(null);
            var userData = _repository.AddUserWhenNameIsNew(name, position.Latitude, position.Longitude, iconUrl);

            if (userData == null)
                return 0;

            return userData.Id;


            //if (FindUser(_users, name) != null)
            //    return 0;

            //lock (_users)
            //{
            //    if (FindUser(_users, name) != null)
            //        return 0;

            //    var newUser = new ChatBoxUser(name,"","",position);
            //   // var newUser = new ChatBoxUser(name);

            //   _users.Add(newUser);

            //    return FindUser(_users,name).Id;
            //}
        }
        public int Register(string name, string nickName, string iconUrl, Position position)
        {
            iconUrl = PrepareIconUrl(iconUrl);

            var userData = _repository.AddUserWhenNameIsNew(name, position.Latitude, position.Longitude, iconUrl, nickName);

            if (userData == null)
                return 0;

            return userData.Id;
        }

        private static string PrepareIconUrl(string iconUrl)
        {
            Random r = new Random();
            int i = r.Next(1, 10);

            if (string.IsNullOrEmpty(iconUrl))
                iconUrl = "char" + i + ".png";

            iconUrl = "characters/" + iconUrl;
            return iconUrl;
        }

        public List<ChatBoxUser> GetCurrentUsers()
        {
            var usersData = _repository.GetAllUsersOnline();

            var users = new List<ChatBoxUser>();
            if (usersData != null)
            {

                foreach (var userData in usersData)
                {
                    var newUser = new ChatBoxUser(userData);
                    users.Add(newUser);
                }


            }
            return users;
        }

        public bool ClearList()
        {
            _repository.ClearUsers();
            return true;

            //lock (_users)
            //{
            //    _users.Clear();
            //    return true;
            //}
        }

        public IList<ChatBoxMessage> GetLastMessages(int id)
        {
            //UpdateLastSeen(id);

            //if (GetCurrentUsers().FindLast(e => e.Id == id) == null)
            //{
            //    return new List<ChatBoxMessage>();
            //}
            //var lastMessages = _messages.Skip(Math.Max(0, _messages.Count() - 5)).Take(5);
            //var listMessages = new List<ChatBoxMessage>();
            //foreach (var m in lastMessages)
            //{
            //    listMessages.Add(m);
            //}
            //return listMessages;

            IList<IChatBoxMessageData> messages = _repository.GetLastMessages(id);
            IList<ChatBoxMessage> messagesconverted = new List<ChatBoxMessage>();
            foreach (IChatBoxMessageData chatBoxMessageData in messages)
            {
                ChatBoxUser u = new ChatBoxUser(chatBoxMessageData.User);
                //met entity framework dit enablen:
                ChatBoxMessage m = new ChatBoxMessage(u, chatBoxMessageData.Message);
                messagesconverted.Add(m);

            }
            return messagesconverted;
        }

        public bool SendMessage(int id, string message)
        {
            //var user = GetCurrentUsers().FindLast(e => e.Id == id);
            //if (user == null) return false;
            //else
            //{
            //    _messages.Add(new ChatBoxMessage(user, message));
            //    return true;
            //}

            IChatBoxUserData user = _repository.GetAllUsersOnline().FindLast(e => e.Id == id);
            if (user == null) return false;
            else
            {
              return  _repository.SendMessage(id, message);
            }
        }

        //private static ChatBoxUser FindUser(IList<ChatBoxUser> list, string name)
        //{
        //    //foreach (var user in list)
        //    //{
        //    //    if (string.Equals(user.Name, name))
        //    //        return user;
        //    //}
        //    //return null;
           
        //}


        internal void Clear()
        {
            _repository.ClearUsers();

            //lock (_users)
            //{
            //    _users.Clear();
            //}
        }

        internal void UpdateLastSeen(int id)
        {
            _repository.UpdateLastSeen(id);

            //var user = _users.ToList().FindLast(e => e.Id == id);
            //if (user != null)
            //    user.LastSeen = DateTime.Now;
        }





        public IList<string> GetImages()
        {
            List<string> imgs = new List<string>();
            imgs.Add("char1.png");
            imgs.Add("char2.png");
            imgs.Add("char3.png");
            imgs.Add("char4.png");
            imgs.Add("char5.png");
            imgs.Add("char6.png");
            imgs.Add("char7.png");
            imgs.Add("char8.png");
            imgs.Add("char9.png");
            imgs.Add("char10.png");
            return imgs;
        }
    }
}
